//
//  HJTWaterView.m
//  WaveAnimationDemo
//
//  Created by jintao he on 2018/12/19.
//  Copyright © 2018 jintao he. All rights reserved.
//

#import "HJTWaterView.h"
#import <CoreText/CoreText.h>

@interface WeakRef : NSProxy

@property (weak) id ref;

- (id)initWithObject:(id)object;

@end

@implementation WeakRef

- (id)initWithObject:(id)object{
    self.ref = object;
    return self;
}

- (void)forwardInvocation:(NSInvocation *)invocation{
    invocation.target = self.ref;
    [invocation invoke];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel{
    return [self.ref methodSignatureForSelector:sel];
}

@end

//------------------------------------------------

@interface HJTWaterView (){
    float a;
    float b;
    BOOL add;
}

@property (nonatomic, strong) CADisplayLink *displayLink;

@end

@implementation HJTWaterView

- (void)dealloc {
    [_displayLink invalidate];
}

-(instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)setup {
    self.backgroundColor = [UIColor clearColor];
    a = 1.5;
    b = 0;
    add = NO;
    
//    [NSTimer scheduledTimerWithTimeInterval:.05 target:self selector:@selector(animateWave) userInfo:nil repeats:YES];
    
    _displayLink = [CADisplayLink displayLinkWithTarget:[[WeakRef alloc] initWithObject:self] selector:@selector(animateWave)];
    [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}

-(void)animateWave{
    if (add) {
        a += 0.01;
    }else{
        a -= 0.01;
    }
    
    if (a<=1) {
        add = YES;
    }
    
    if (a>=1.5) {
        add = NO;
    }
    
    b+=0.1;
    
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect{
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGMutablePathRef path = CGPathCreateMutable();
    
    CGContextSetLineWidth(context, 1);
    CGContextSetFillColorWithColor(context, [self.waterColor CGColor]);
    
    float y = self.waterLevelY;
    CGPathMoveToPoint(path, NULL, 0, y);
    
    for(float x = 0; x <= 320; x++) {
        @autoreleasepool {
            y = a * sin(x/180*M_PI + 4*b/M_PI) * 5 + self.waterLevelY;
            CGPathAddLineToPoint(path, nil, x, y);
        }
    }
    
    CGPathAddLineToPoint(path, nil, 320, rect.size.height);
    CGPathAddLineToPoint(path, nil, 0, rect.size.height);
    CGPathAddLineToPoint(path, nil, 0, self.waterLevelY);
    
    CGContextAddPath(context, path);
    CGContextFillPath(context);
    CGContextDrawPath(context, kCGPathStroke);
    
    [self.waveDelegate wavePath:path];
    
    CGPathRelease(path);
}

@end
